package com.fstart.sys.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fstart.common.Result;
import com.fstart.common.Utils;
import com.fstart.sys.entity.EmailCode;
import com.fstart.sys.entity.User;
import com.fstart.sys.entity.constants.Constants;
import com.fstart.sys.entity.dto.CreateImageCode;
import com.fstart.sys.entity.dto.UserDto;
import com.fstart.sys.service.IEmailCodeService;
import com.fstart.sys.service.IUserService;
import org.apache.ibatis.io.ResolverUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpRequest;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author Xibing
 * @since 2023-04-23
 */
@RestController
@RequestMapping("/sys/user")
public class UserController {
    @Autowired
    private IUserService userService;

    @Autowired
    private IEmailCodeService emailCodeService;

    @Autowired
    private PasswordEncoder passwordEncoder;



    // 登录
    @PostMapping("/login")
    public Result<Map<String, Object>> login(@RequestBody User user) {
        // 查询数据库，没有数据则登录失败
        Map<String, Object> data = userService.login(user);

        if (data != null) {
            return Result.success(data, "用户登录成功");
        }
        return Result.fail(20002, "用户名或密码错误");
    }

    // info用户信息
    @GetMapping("/info")
    public Result<?> getUserInfo(@RequestParam("token") String token) {
        //根据token获取用户信息,redis
        Map<String, Object> data = userService.getUserinfo(token);

        if (data != null) {
            return Result.success(data);
        }

        return Result.fail(20003, "用户登录信息无效，请重新登录");
    }

    // 退出
    @PostMapping("/logout")
    public Result<?> logout(@RequestHeader("X-Token") String token) {
        // 删除redis中的用户信息
        userService.logout(token);

        return Result.success();
    }

    // 发送邮箱验证码
    @PostMapping("/getEmailCode")
    public Result<?> getEmailCode(@RequestBody Map<String, String> email){

        if("FStart:注册验证码".equals(email.get("message"))){
            LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(User::getEmail, email.get("email"));

            User one = userService.getOne(wrapper);
            if(one != null){
                return Result.fail("邮箱已存在");
            }
        }

        if("FStart:忘记密码".equals(email.get("message"))){
            LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(User::getEmail, email.get("email"));

            User one = userService.getOne(wrapper);
            if(one == null){
                return Result.fail("该邮箱尚未注册，请先注册");
            }
        }

        boolean sendFlag = userService.sendEmailCode(email);

        if(!sendFlag){
            return Result.fail("验证码发送失败，请检查邮箱是否存在。");
        }

        return Result.success("验证码发送成功");
    }


    @PostMapping("/checkCodeIsOk")
    public Result<?> checkCodeIsOk(@RequestBody EmailCode emailCode){
        // 根据邮箱和验证码查询
        if(emailCode == null) return Result.fail("请输入邮箱或验证码");


        if(emailCode.getCode().equals("")
                || emailCode.getEmail().equals("")
                || emailCode.getEmail() == null
                || emailCode.getCode() == null
        ){
            return Result.fail("请输入邮箱或验证码");
        }

        LambdaQueryWrapper<EmailCode> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EmailCode::getEmail, emailCode.getEmail());
        wrapper.eq(EmailCode::getCode, emailCode.getCode());
        wrapper.eq(EmailCode::getStatus, "0");

        EmailCode code = emailCodeService.getOne(wrapper);

        if(code == null){
            return Result.fail("请检查验证码或邮箱是否输入正确!");
        }

        // 检测验证码是否过期
        LocalDateTime createTime = code.getCreateTime();

        // 判断时间 5分钟内有效
        Duration duration = Duration.between(createTime, LocalDateTime.now());
        if(duration.toMinutes() > 5){
            return Result.fail("验证码失效,请在生成的5分钟内使用。");
        }


        return Result.success("验证码输入正确");
    }
    // 注册用户
    @PostMapping("/register")
    public Result<?> register(@RequestBody UserDto user) {

        // 检测邮箱格式是否正确
        // 检测邮箱是否存在
        LambdaQueryWrapper<User> wrapperByEmail = new LambdaQueryWrapper<>();
        wrapperByEmail.eq(User::getEmail, user.getEmail());

        User identificationByEmail = userService.getOne(wrapperByEmail);
        if (identificationByEmail != null) {
            return Result.fail(20001, "邮箱已存在");
        }

        // 判断验证码是否有效
        LambdaQueryWrapper<EmailCode> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EmailCode::getEmail, user.getEmail());
        wrapper.eq(EmailCode::getCode, user.getCheckCode());
        wrapper.eq(EmailCode::getStatus, "0");

        EmailCode emailCode = emailCodeService.getOne(wrapper);

        // 验证码是否生成
        if(emailCode == null){
            return Result.fail("验证码输入错误,请检查验证码！");
        }

        // 验证码状态是否可用
        if(emailCode.getStatus().equals("1")){
            return Result.fail("验证码已使用");
        }

        LocalDateTime createTime = emailCode.getCreateTime();

        // 判断时间 5分钟内有效
        Duration duration = Duration.between(createTime, LocalDateTime.now());
        if(duration.toMinutes() > 5){
            return Result.fail("验证码失效,请在生成的5分钟内使用。");
        }


        // 设置状态为启用
        emailCode.setStatus("1");
        LambdaQueryWrapper<EmailCode> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(EmailCode::getId, emailCode.getId());

        emailCodeService.update(emailCode, wrapper1);

        // 检测用户名是否存在
        LambdaQueryWrapper<User> wrapperByName = new LambdaQueryWrapper<>();
        wrapperByName.eq(User::getUsername, user.getUsername());


        User identificationByName = userService.getOne(wrapperByName);
        if (identificationByName != null) {
            return Result.fail(20001, "用户名字已存在");
        }

        // 密码加密
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        // 设置用户默认状态
        user.setStatus(1);
        // 设置用户默认头像
        user.setAvatar("https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
        // 设置注册时间
        user.setCreateTime(LocalDateTime.now());
        // 保存用户
        userService.save(user);
        // 返回成功标识
        return Result.success("注册成功");
    }

    /**
     * 修改用户头像
     *
     * @return
     */
    @PutMapping("/updateUserTop")
    public Result<?> updateUserTop(@RequestBody User user, @RequestHeader("X-Token") String token) {
        // 更具id查询用户
        System.out.println(user.toString());
        User userById = userService.updateUserTop(user, token);
        if (userById == null) {
            return Result.fail("没有该用户");
        }
        // 修改头像
        userById.setAvatar(user.getAvatar());
        userService.updateById(userById);
        return Result.success("修改成功");
    }


    @PutMapping("/updatePassword")
    public Result<?> updatePassword(@RequestBody Map<String, String> user) {
        // 更具用户id和查询用户
        User byId = userService.getById(user.get("id"));
        if (byId == null) {
            return Result.fail("用户不存在，修改失败。");
        } else {
            // 判断原密码真不正确
            boolean isOk = passwordEncoder.matches(user.get("password"), byId.getPassword());
            // 原密码输入正确则修改密码
            if (!isOk) return Result.success("原密码不正确哦~");

            byId.setPassword(passwordEncoder.encode(user.get("uPassword")));
            userService.updateById(byId);
        }
        return Result.success("修改成功");
    }

    /**
     * 忘记密码
     */
    @PutMapping("/updatePasswordByEmailCode")
    public Result<?> updatePasswordByEmailCode(@RequestBody Map<String, String> userInfo){
        // 判断验证码是否正确
        if (userInfo == null) return Result.fail("请输入验证信息");

        String code = userInfo.get("code");
        String email = userInfo.get("email");
        String password = userInfo.get("password");

        if(password.equals("") || userInfo.get("password") == null){
            return Result.fail("请输入密码");
        }

        System.out.println(userInfo.toString());

        LambdaQueryWrapper<EmailCode> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EmailCode::getCode, code);
        wrapper.eq(EmailCode::getEmail, email);
        wrapper.eq(EmailCode::getStatus, "0");

        EmailCode one = emailCodeService.getOne(wrapper);

        // 判断验证码是否正确
        if (one == null){
            return Result.fail("请检测验证码是否输入正确");
        }

        // 检测验证码是否过期
        LocalDateTime createTime = one.getCreateTime();

        // 判断时间 5分钟内有效
        Duration duration = Duration.between(createTime, LocalDateTime.now());
        if(duration.toMinutes() > 5){
            return Result.fail("验证码失效,请在生成的5分钟内使用。");
        }

        // 设置状态
        // 设置状态为启用
        one.setStatus("1");
        LambdaQueryWrapper<EmailCode> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(EmailCode::getId, one.getId());

        emailCodeService.update(one, wrapper1);

        // 修改密码
        LambdaQueryWrapper<User> wrapper2 = new LambdaQueryWrapper<>();
        wrapper2.eq(User::getEmail, one.getEmail());

        User byEmail = userService.getOne(wrapper2);
        if(byEmail == null){
            return Result.fail("该邮箱尚未注册，请先注册");
        }

        // 加密
        byEmail.setPassword(passwordEncoder.encode(password));
        userService.updateById(byEmail);

        return Result.success("修改成功");
    }


}
